-
Notifications
You must be signed in to change notification settings - Fork 844
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[EuiDataGrid] Simplify & DRY out cell/header focus #7448
Conversation
- there's enough now that it's clogging up the `body/` folder and it makes sense to
- all of the removed methods are now totally unnecessary and handled as-is by `HandleInteractiveChildren`
…state + misc imports reorder/reorg
- cell actions are rendered in the DOM, just not visible, which saves us from having to add a bunch of extra hover/focus state trackers
- all of the removed methods are now totally unnecessary and handled as-is by `HandleInteractiveChildren
- auto focus the column header actions button instead of the wrapping grid cell, as it contains more SR information than just the cell - fix cell focus border to appear correctly as before - write E2E Cypress tests to replace old Jest tests
+ better header focus trap testing
- removes the need for a bunch of extra state/props, a mutation observer, hooks, etc. - it really doesn't add anything except extra cruft and inconsistency to have the header not be navigable to, hence this entire PR removing it
- to account for header now always being navigable no matter what
- remove unnecessary `getGridData()` call which isn't asserting on anything
- my local vscode doesn't complain about this, but CLI does - not totally sure why or if this makes sense :|
c767730
to
e0a1584
Compare
e0a1584
to
41ed92e
Compare
@1Copenut Hey hey! I was hoping you could review this since this is primarily accessibility driven in improvements (in addition to the side benefit of lots of DRYing out/removal of code) 🙏 |
8a2868d
to
d6c70f6
Compare
@1Copenut Header focus fighting should be fixed once staging is done updating! Thank you so much for catching that bug! |
- caused by race condition with ref not updating `HandleInteractiveChildren`
9f8601e
to
1d9e46f
Compare
Preview staging links for this PR:
|
💚 Build Succeeded
History
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀 LGTM! I tested the QA requirements you laid out in two rounds--one before we discovered the regression in header row behavior and once after to verify the fix. This gave me two opportunities to drive the new UX for handling rows with one interactive element.
This was the right call, to make cells with 1 or N interactive elements behave the same. I was able to internalize the pattern quickly and didn't feel the extra click to do things like open the Actions menu was an inconvenience.
Testing groups:
- Evergreen browsers [Chrome, Firefox, Edge, Safari]
- MacOS Safari + VoiceOiver
- Win10 Firefox + NVDA
- Win10 Chrome + NVDA
- Win10 Chrome + JAWS
<EuiI18n | ||
// eslint-disable-next-line local/i18n | ||
token="euiDataGridCell.focusTrapEnterPrompt" | ||
default="Press the Enter key to interact with this cell's contents." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the one thing I've been mulling over in testing. I love the clear directions to enter the focus trap. I wonder if we need explanation to exit the focus trap via the ESC
key. My hunch is no, at least until data tells us otherwise. I wonder if the Research team would be up for a screen reader testing session.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering that as well - thanks for raising it! I think I also lean towards waiting to see if it's needed before adding. I'd love for us to start doing screen reader research!
* This internal utility component is used by all cells, both header and body/footer cells. | ||
* It always handles: | ||
* 1. Removing any interactive children from keyboard tab order on cell mount | ||
* 2. Listening for focus on any interactive children and updating the cell focus context | ||
* | ||
* It should *only* render focus traps for: | ||
* 1. Header cells that are `actions: false` but still have interactive children | ||
* 2. Body cells that are `isExpandable: false` but still have interactive children | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This explanation of the utility was especially helpful in QA testing. Between this documentation and the clear separation of concerns, I was able to answer 90% of my own questions. This is greatly appreciated by me and will pay dividends for future consumers. Thanks Cee!
* focus trap that can be entered with the Enter key, which cycles keyboard tabs | ||
* through the cell contents only, and exited with the Escape key | ||
*/ | ||
export const FocusTrappedChildren: FunctionComponent< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This drives so much better with screen readers, having one interaction pattern for 1 or N number of interactive elements. It felt natural and I didn't notice the extra click.
Thanks a million for the QA and feedback Trevor!! Super happy this was a net screen reader improvement ✨ Going to merge this in after today's release to spread out changes a bit. |
`v92.0.0-backport.0`⏩ `v92.1.1` --- ## [`v92.1.1`](https://github.com/elastic/eui/releases/v92.1.1) **Bug fixes** - Minor `EuiDataGrid` cell performance fixes ([#7465](elastic/eui#7465)) ## [`v92.1.0`](https://github.com/elastic/eui/releases/v92.1.0) - Updated `EuiResizableButton` to allow customizing the `indicator` style with either `handle` (default) or `border` ([#7455](elastic/eui#7455)) - Enhanced `EuiResizableContainer` to preserve the drag/resize event when the user's mouse leaves the parent container and re-enters ([#7456](elastic/eui#7456)) **Bug fixes** - Fixed an `EuiTreeView` JSX Typescript error ([#7452](elastic/eui#7452)) - Fixed a color console warning being generated by disabled `EuiStep`s ([#7454](elastic/eui#7454)) **Accessibility** - `EuiDataGrid`'s keyboard/screenreader experience has been tweaked to be more consistent for varying complex data: ([#7448](elastic/eui#7448)) - Headers are now always navigable by arrow key, regardless of whether the header cells contain interactive content - Non-expandable cells containing any amount of interactive content now must be entered via Enter or F2 keypress - Expandable cells continue to be toggled via Enter or F2 keypress - `EuiDataGrid` now provides a direct screen reader hint for Enter key behavior for expandable & interactive cells ([#7448](elastic/eui#7448))
`v92.0.0-backport.0`⏩ `v92.1.1` --- ## [`v92.1.1`](https://github.com/elastic/eui/releases/v92.1.1) **Bug fixes** - Minor `EuiDataGrid` cell performance fixes ([elastic#7465](elastic/eui#7465)) ## [`v92.1.0`](https://github.com/elastic/eui/releases/v92.1.0) - Updated `EuiResizableButton` to allow customizing the `indicator` style with either `handle` (default) or `border` ([elastic#7455](elastic/eui#7455)) - Enhanced `EuiResizableContainer` to preserve the drag/resize event when the user's mouse leaves the parent container and re-enters ([elastic#7456](elastic/eui#7456)) **Bug fixes** - Fixed an `EuiTreeView` JSX Typescript error ([elastic#7452](elastic/eui#7452)) - Fixed a color console warning being generated by disabled `EuiStep`s ([elastic#7454](elastic/eui#7454)) **Accessibility** - `EuiDataGrid`'s keyboard/screenreader experience has been tweaked to be more consistent for varying complex data: ([elastic#7448](elastic/eui#7448)) - Headers are now always navigable by arrow key, regardless of whether the header cells contain interactive content - Non-expandable cells containing any amount of interactive content now must be entered via Enter or F2 keypress - Expandable cells continue to be toggled via Enter or F2 keypress - `EuiDataGrid` now provides a direct screen reader hint for Enter key behavior for expandable & interactive cells ([elastic#7448](elastic/eui#7448))
Summary
closes #5690
As always, please follow along by commit. While it looks like more lines of code were added in this PR, those were primarily all tests (a good thing to have more of) and snapshots diffs. From actual source code, a net ~500 or so lines were removed.
Main changes in this PR:
I removed all logic around detecting
headerIsInteractive
. From now on, data grid headers can ALWAYS be navigated to via arrow keys, regardless of whether or not header cells have interactive content or not.Non-expandable cells that only contain 1 interactive child element no longer auto-focus that element, but instead render a focus trap
isExpandable: false
and have 1 interactive child #5690, accessibility concerns) where other non-interactive content in the cell would not be accessible to keyboard users.Cell screen reader text now contains instructions for the
Enter
keypress behavior in addition to current column position.For the majority of default EuiDataGrid use cases (expandable cells & column headers with actions), nothing should have changed or regressed from before.
QA
Enter
key on the non-expandable cells with interactive links/buttons inside them (both header and data cells) enters a focus trapEscape
keyGeneral checklist
- [ ] Checked in both light and dark modes- [ ] Checked in mobile- [ ] Props have proper autodocs (using@default
if default values are missing) and playground toggles- [ ] Checked Code Sandbox works for any docs examples- [ ] If applicable, added the breaking change issue label (and filled out the breaking change checklist)- [ ] Updated the Figma library counterpart